﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ExchangeListener
{
    class ExchangeContacts
    {
        private ExchangeContacts()
        { }

        private static ExchangeContacts ec;

        public static ExchangeContacts Instance
        {
            get
            {
                if (ec == null)
                    ec = new ExchangeContacts();
                return ec;
            }
        }

        public ContactItemType[] GetExchangeContactItems(ExchangeServiceBinding esb)
        {
            FindItemResponseType response = esb.FindItem(new FindItemType
            {
                ItemShape = new ItemResponseShapeType
                {
                    BaseShape = DefaultShapeNamesType.AllProperties,
                },
                ParentFolderIds = new DistinguishedFolderIdType[] 
                        { 
                            new DistinguishedFolderIdType { Id = DistinguishedFolderIdNameType.contacts }, 
                        },
            });

            ItemType[] items = ((ArrayOfRealItemsType)((FindItemResponseMessageType)response.ResponseMessages.Items[0]).RootFolder.Item).Items;

            List<ContactItemType> lcit = new List<ContactItemType>();

            if (items != null)
            {
                foreach (var item in items)
                {
                    ContactItemType cit = (ContactItemType)item;
                    cit.LastModifiedTime = GetLastModified(cit.ItemId.Id, esb);
                    lcit.Add(cit);
                }
            }
            return lcit.ToArray();
        }

        /// <summary>
        /// 获取最后更新时间, 代码来源 http://blogs.msdn.com/b/vikas/archive/2007/10/16/howto-ews-lastmodifiedtime-is-missing-too.aspx
        /// </summary>
        /// <param name="itemID"></param>
        /// <param name="esb"></param>
        /// <returns></returns>
        public DateTime GetLastModified(string itemID, ExchangeServiceBinding esb)
        {
            DateTime dtRet = new DateTime();

            PathToExtendedFieldType[] ptufta = new PathToExtendedFieldType[1];

            ptufta[0] = new PathToExtendedFieldType();

            ptufta[0].PropertyTag = "0x3008"; //Property Tag for LastModifiedTime

            ptufta[0].PropertyType = MapiPropertyTypeType.SystemTime;

            ItemResponseShapeType irst = new ItemResponseShapeType();

            irst.BaseShape = DefaultShapeNamesType.IdOnly;

            irst.AdditionalProperties = ptufta;

            ItemIdType[] biita = new ItemIdType[1];

            biita[0] = new ItemIdType();

            biita[0].Id = itemID;

            //get the item

            GetItemType git = new GetItemType();

            git.ItemShape = irst;

            git.ItemIds = biita;

            GetItemResponseType girt = esb.GetItem(git);

            ItemType MsgItem = null;

            if (girt.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Success)
                MsgItem = ((ItemInfoResponseMessageType)girt.ResponseMessages.Items[0]).Items.Items[0];

            if (null != MsgItem)

                DateTime.TryParse(MsgItem.ExtendedProperty[0].Item.ToString(), out dtRet);

            return dtRet;



        }

        public bool CreateNewExchangeContact(ContactItemType cit, ExchangeServiceBinding esb)
        {
            try
            {               
                CreateItemType createRequest = new CreateItemType();
                
                createRequest.SavedItemFolderId = new TargetFolderIdType();
                DistinguishedFolderIdType contactsFolder = new DistinguishedFolderIdType();
                contactsFolder.Id = DistinguishedFolderIdNameType.contacts;
                createRequest.SavedItemFolderId.Item = contactsFolder;

                createRequest.Items = new NonEmptyArrayOfAllItemsType();
                createRequest.Items.Items = new ItemType[1];

                cit.ItemId = null;
                cit.FileAs = null;
                cit.FileAsMapping = FileAsMappingType.None;
                cit.FileAsMappingSpecified = false;
                
                createRequest.Items.Items[0] = cit;

                CreateItemResponseType createresponse = esb.CreateItem(createRequest);
                if (createresponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Success)
                    return true;
                else
                {
                    Console.WriteLine(createresponse.ResponseMessages.Items[0].MessageText);
                    return false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;

            }

        }

        public bool UpdateExchangeContact(ContactItemType cit,ExchangeServiceBinding esb)
        {
            try
            {
                UpdateItemType updateRequest = new UpdateItemType();

                updateRequest.ConflictResolution = ConflictResolutionType.AlwaysOverwrite;

                updateRequest.ItemChanges = new ItemChangeType[1];
                ItemChangeType changetype = new ItemChangeType();
                
                changetype.Item = cit.ItemId;

                SetItemFieldType updateitem = new SetItemFieldType();

                PathToIndexedFieldType path = new PathToIndexedFieldType();
                path.FieldIndex = PhoneNumberKeyType.MobilePhone.ToString();
                path.FieldURI = DictionaryURIType.contactsPhoneNumber;
                updateitem.Item = path;            

                //PathToUnindexedFieldType path = new PathToUnindexedFieldType();
                //path.FieldURI =  UnindexedFieldURIType.contactsPhoneNumbers;
                //updateitem.Item = path;                

                ContactItemType tempcontact = new ContactItemType();
                tempcontact.PhoneNumbers = cit.PhoneNumbers;
                updateitem.Item1 = tempcontact;                

                changetype.Updates = new ItemChangeDescriptionType[] { updateitem };               

                updateRequest.ItemChanges[0] = changetype;
                
                UpdateItemResponseType uirt = esb.UpdateItem(updateRequest);
                if (uirt.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Success)
                    return true;
                else
                {
                    Console.WriteLine(uirt.ResponseMessages.Items[0].MessageText);
                    return false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }

        public bool AddMobilePhoneNumber(ContactItemType cit, ExchangeServiceBinding esb)
        {
            try
            {
                DeleteItemType deleterequest = new DeleteItemType();
                deleterequest.ItemIds = new BaseItemIdType[1];
                deleterequest.ItemIds[0] = cit.ItemId;
                deleterequest.DeleteType = DisposalType.HardDelete;

                DeleteItemResponseType dirt = esb.DeleteItem(deleterequest);
                if (dirt.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Success)
                {
                    return this.CreateNewExchangeContact(cit, esb);
                }
                else
                {
                    Console.WriteLine(dirt.ResponseMessages.Items[0].MessageText);
                    return false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }
    }
}
